Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

298
Visualizações
¿Puede "sizeof (arr [0])" conducir a un comportamiento indefinido?

Hay un patrón bien conocido para calcular la longitud de la matriz:

 int arr[10]; size_t len = sizeof(arr) / sizeof(arr[0]); assert(len == 10);

Este patrón se aplica a arreglos estáticos y arreglos automáticos de tamaño constante. También se aplica a matrices de longitud variable en C99.

Quiero aplicar una idea similar para calcular el tamaño de la matriz dinámica en bytes:

 size_t known_len = 10; int *ptr = malloc(known_len * sizeof(int)); size_t size = known_len * sizeof(ptr[0]); assert(size == known_len * sizeof(int));

Esto es mejor que known_len * sizeof(int) porque sizeof(ptr[0]) no se refiere al tipo de elemento de matriz real. Por lo tanto, no requiere que el lector del código sepa el tipo.

Sin embargo, no me queda claro si la expresión sizeof(ptr[0]) puede conducir a un comportamiento indefinido. Como se expande:

 sizeof(ptr[0]) -> sizeof(*((ptr) + (0))) -> sizeof(*ptr)

La expresión del resultado es cuestionable en caso de que ptr sea 0 :

 sizeof(*((int*) 0))

Según un estándar C99:

(C99, 6.3.2.3p3): "Una expresión constante de entero con el valor 0 , o una expresión de este tipo convertida en tipo void * , se denomina constante de puntero nulo". Eliminar la referencia a un puntero nulo es un comportamiento indefinido.

(C99, 6.5.3.2.p4) "Si se ha asignado un valor no válido al puntero, el comportamiento del operador unario * no está definido.87)"

87): "Entre los valores no válidos para desreferenciar un puntero mediante el operador unario * se encuentran un puntero nulo, una dirección alineada inapropiadamente para el tipo de objeto al que apunta y la dirección de un objeto después del final de su vida útil".

Pero nunca se especifica si el tamaño de dicha expresión puede conducir a un comportamiento indefinido. De hecho, tal sizeof debe evaluarse en tiempo de compilación.

Mis preguntas son:

  • ¿Se puede usar la expresión sizeof(ptr[0]) en el código cuando se conoce el tipo de ptr y no se conoce el valor de ptr ?
  • ¿Se puede justificar tal uso según el estándar C99? ¿Especificaciones GNU GCC?
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

La expresión ptr[0] no se evaluará en sizeof(ptr[0]) . El tamaño se determinará simplemente usando el tipo de ptr[0] en tiempo de compilación.

C11: 6.5.3.4:

El operador sizeof produce el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo. El tamaño se determina a partir del tipo del operando . El resultado es un número entero. Si el tipo del operando es un tipo de matriz de longitud variable, se evalúa el operando; de lo contrario, el operando no se evalúa y el resultado es una constante entera.

Eso significa que no hay un comportamiento indefinido.

over 4 years ago · Santiago Trujillo Relatório

0

Esto no causará un comportamiento indefinido.

Con la excepción de tomar el tamaño de matrices de longitud variable, sizeof es una expresión constante en tiempo de compilación. El compilador procesa la expresión para determinar su tipo, sin producir el código para evaluar la expresión en tiempo de compilación. Por lo tanto, el valor en ptr[0] (que es un puntero no inicializado) no importa en absoluto.

Además, si desea asignar diez números enteros, debe llamar a malloc de esta manera:

 int *ptr = malloc(known_len * sizeof(ptr[0]));

De lo contrario, asigna diez bytes, que es demasiado pequeño para almacenar diez enteros. Tenga en cuenta que en la expresión anterior, ptr no está inicializado en el momento de la llamada, lo que está perfectamente bien para sizeof .

over 4 years ago · Santiago Trujillo Relatório

0

En el caso general, si me falta algo, la desreferenciación de un puntero nulo en sizeof puede conducir a un comportamiento indefinido. Desde C99, sizeof no es una construcción puramente de tiempo de compilación. El operando de sizeof se evalúa en tiempo de ejecución si el tipo de operando es un VLA.

Considere el siguiente ejemplo

 unsigned n = 10; int (*a)[n] = NULL; // `a` is a pointer to a VLA unsigned i = 0; sizeof a[i++]; // applying `sizeof` to a VLA

De acuerdo con el estándar C99, se supone que se evalúa el argumento de sizeof (es decir, se supone que i se incrementa). Sin embargo, no estoy completamente seguro de que se suponga que la desreferencia de punto nulo en a[0] produzca un comportamiento indefinido aquí.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda